Creé una entrada de número de tipo. Valor mínimo 1, valor máximo 100. Paso 5. Sin embargo, puedo ingresar valores distintos al paso para esta entrada. Por ejemplo, 7 en lugar de 5-10-15.
Me gustaría que los valores ingresados manualmente se incrementen automáticamente al valor del paso. El usuario ingresa 7; después de dejar la entrada, es 10. Estoy intentando enfocarme pero no tengo idea de cómo hacerlo.
<input type="number" min="1" max="100" step="5" onfocusout="this.value = Math.round(step);">Ejemplo. El usuario ingresa 13 - obtiene 15. Ingresa 27 - obtiene 30.
puedes :
obtener el resultado del valor dividido por 5
redondear el resultado a casi entero
y multiplíquelo por 5 para obtener el valor 5 más cercano de la entrada ingresada por el usuario
this.value = Math.round(this.value / 5) * 5; <input type="number" min="1" max="100" step="5" onfocusout="var result = Math.round(this.value / 5) * 5; this.value = (result) ? result : this.min ;">Primero, en lugar de escuchar los eventos de focusout , debe escuchar los eventos de change , que se activan cada vez que el usuario hace algo que implica que ha terminado de ingresar un valor. Esto hará que el comportamiento sea más consistente entre navegadores y dispositivos.
En segundo lugar, puede redondear un valor al múltiplo más cercano de X haciendo Math.round(value / X) * X , y puede restringir un valor dentro de [A, B] usando Math.min(Math.max(A, value), B) .
Finalmente, los atributos HTML min , max y step corresponden directamente a las propiedades en el objeto HTMLInputElement de JavaScript, que es el objeto vinculado a this dentro del detector de eventos.
Combinando todo esto, obtienes esto.
<input type="number" min="1" max="100" step="5" onchange="this.value = Math.min(Math.max(this.min, Math.round(this.value / this.step) * this.step), this.max)"> Tenga en cuenta que en su código, el atributo min es 1 , que no es un múltiplo de 5 , y eso le dice al navegador que acepte valores en la secuencia [1, 6, 11, 16, ...] que rompe nuestro código. Si desea múltiplos de 5, deberá asegurarse de que el atributo mínimo también sea un múltiplo de 5.
Todo ese código JS dentro de un atributo HTML es difícil de leer, por lo que es posible que desee utilizar un detector de eventos adecuado en este punto, lo que le permite dividir el problema en funciones más pequeñas.
function clamp(a, value, b) { return Math.min(Math.max(a, value), b); } function roundTo(multiple, value) { return Math.round(value / multiple) * multiple; } function roundToStepOnChange(event) { const roundedValue = roundTo(this.step, this.value); const clampedValue = clamp(this.min, roundedValue, this.max); this.value = clampedValue; } document.getElementById("myInput").addEventListener("change", roundToStepOnChange); <input id="myInput" type="number" min="5" max="100" step="5">Establecí el atributo mínimo en 5 en ese ejemplo para que pueda verlo funcionando sin problemas.